﻿using System;
using System.Collections.Generic;
using CookComputing.XmlRpc;
//
using PerceptiveMCAPI.Types;

namespace PerceptiveMCAPI.Methods
{
   public class ecommAddOrder : Api_BaseExecute
   {
      private new ecommAddOrderInput Input { get; set; }
      private ecommAddOrderOutput Output { get; set; }
      // =============================================== constructors
      public ecommAddOrder() { }
      public ecommAddOrder( ecommAddOrderInput input ) { this.Input = input; }

      #region =============================================== Mainline Execute

      public ecommAddOrderOutput Execute()
      {
         // empty constructor & Execute() is bad
         if ( Input == null )
            throw new ArgumentException( "Input class not provided" );
         // do the deed
         Output = Execute( Input );
         return Output;
      }
      // ---------------------------------------------
      public ecommAddOrderOutput Execute( ecommAddOrderInput input )
      {
         Input = input;
         Output = new ecommAddOrderOutput( Input );
         ValidationIsOK = true;
         //------------------------- validate it
         if ( Input.api_Validate )
         {
            Output.api_ValidatorMessages = ValidateInput.Validate( Input );
            ValidationIsOK = ValidateInput.IsOK( Output.api_ValidatorMessages );
         }
         //------------------------- do it
         if ( ValidationIsOK )
         {
            ApiRun( Input, input.parms.apikey );  // execute API & format output
         }
         // ---
         return Output;
      }
      #endregion

      #region ================================================================= API Calls
      // // ---------------------------------------------------------- XmlRpc
      protected override void ExecuteXmlRpc()
      {
         try
         {
            XmlRpcStruct order = formatOrder( Input.parms.order );
            // ---------------------------------- rpc call -------------------------------------------
            bool rpcResult = apiXmlRpc.api.ecommAddOrder( Input.parms.apikey, order );
            // ---------------------------------- rpc output -------------------------------------------
            Output.result = rpcResult;                                  // - Format response
            Output.api_Request = EnumValues.NotSupplied; Output.api_Response = EnumValues.NotSupplied;                // - no  message
         }
         catch ( XmlRpcFaultException fex )
         {
            Output.api_ErrorMessages.Add( apiException.FormatError( fex ) );
         }
         catch ( Exception ex )
         {
            Output.api_ErrorMessages.Add( apiException.FormatError( ex ) );
         }

      }
      private XmlRpcStruct formatOrder( ecommAddOrder_order order )
      {
         XmlRpcStruct rpc = new XmlRpcStruct();
         XmlRpcStruct itm; int i = -1;
         // -------------------------------------
         rpc.Add( "id", order.order_id );
         if ( !string.IsNullOrEmpty( order.email_id ) )
            rpc.Add( "email_id", order.email_id );
         if ( !string.IsNullOrEmpty( order.email ) )
            rpc.Add( "email", order.email );
         rpc.Add( "total", order.total );
         if ( order.order_date > DateTime.MinValue )
            rpc.Add( "order_date", apiHelper.FormatApiDateParm( order.order_date ) );
         rpc.Add( "shipping", order.shipping );
         rpc.Add( "tax", order.tax );
         rpc.Add( "store_id", order.store_id ?? "" );
         rpc.Add( "store_name", order.store_name ?? "" );
         rpc.Add( "campaign_id", order.campaign_id ?? "" );
         rpc.Add( "plugin_id", order.plugin_id ?? "" );
         object[] items = new object[order.items.Count];

         foreach ( ecommOrder_item item in order.items )
         {
            i++;
            itm = new XmlRpcStruct();
            if ( item.line_num > 0 )
               itm.Add( "line_num", item.line_num );
            itm.Add( "product_id", item.product_id );
            itm.Add( "product_name", item.product_name ?? "" );
            itm.Add( "category_id", item.category_id );
            itm.Add( "category_name", item.category_name ?? "" );
            itm.Add( "qty", item.qty );
            itm.Add( "cost", item.cost );
            items[i] = itm;
            //
         }
         rpc.Add( "items", items );
         // -------------------------------------
         return rpc;
      }
      // ---------------------------------------------------------- Serial Post
      protected override void ExecuteSerialPost()
      {
         try
         {
            Dictionary<string, string> dict = new Dictionary<string, string>();
            dict.Add( "apikey", Input.parms.apikey );
            // --------------------------------- order format
            dict.Add( "order[id]", Input.parms.order.order_id );
            if ( !string.IsNullOrEmpty( Input.parms.order.email_id ) )
               dict.Add( "order[email_id]", Input.parms.order.email_id );
            if ( !string.IsNullOrEmpty( Input.parms.order.email ) )
               dict.Add( "order[email]", Input.parms.order.email );
            dict.Add( "order[total]", Input.parms.order.total.ToString( "N2" ) );
            if ( Input.parms.order.order_date > DateTime.MinValue )
               dict.Add( "order[order_date]", apiHelper.FormatApiDateParm( Input.parms.order.order_date ) );
            dict.Add( "order[shipping]", Input.parms.order.shipping.ToString( "N2" ) );
            dict.Add( "order[tax]", Input.parms.order.tax.ToString( "N2" ) );
            dict.Add( "order[store_id]", Input.parms.order.store_id );
            dict.Add( "order[store_name]", Input.parms.order.store_name );
            dict.Add( "order[plugin_id]", Input.parms.order.plugin_id );
            dict.Add( "order[campaign_id]", Input.parms.order.campaign_id );
            int i = -1;
            foreach ( ecommOrder_item item in Input.parms.order.items )
            {
               i++;
               dict.Add( string.Format( "order[items][{0}][line_num]", i ), item.line_num.ToString() );
               dict.Add( string.Format( "order[items][{0}][product_id]", i ), item.product_id.ToString() );
               dict.Add( string.Format( "order[items][{0}][product_name]", i ), item.product_name ?? "" );
               dict.Add( string.Format( "order[items][{0}][category_id]", i ), item.category_id.ToString() );
               dict.Add( string.Format( "order[items][{0}][category_name]", i ), item.category_name ?? "" );
               dict.Add( string.Format( "order[items][{0}][qty]", i ), item.qty.ToString() );
               dict.Add( string.Format( "order[items][{0}][cost]", i ), item.cost.ToString( "N2" ) );
            }
            // -- do it
            string api_Request = "";
            string api_Response = apiSerial.ProcessRequest( Input, dict, out api_Request );
            Output.Format( api_Request, api_Response );
         }
         catch ( Exception ex )
         {
            Output.api_ErrorMessages.Add( apiException.FormatError( ex ) );
         }
      }
      #endregion

   }
}
